/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zh.harmony.lifecycle;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * Internal class to handle lifecycle conversion etc.
 *
 * @hide
 */
public class Lifecycling {
    /**
     * 回调类型，反射
     */
    private static final int REFLECTIVE_CALLBACK = 1;
    /**
     * 回调类型，APT生成
     */
    private static final int GENERATED_CALLBACK = 2;

    /**
     * 回调类型缓存Map，避免每次反射查找构造函数的低效
     */
    private static final Map<Class, Integer> sCallbackCache = new HashMap<>();
    private static final Map<Class, List<Constructor<? extends GeneratedAdapter>>> sClassToAdapters =
            new HashMap<>();

    // Left for binary compatibility when lifecycle-common goes up 2.1 as transitive dep
    // but lifecycle-runtime stays 2.0

    /**
     * @deprecated Left for compatibility with lifecycle-runtime:2.0
     */
    @Deprecated
    static GenericLifecycleObserver getCallback(final Object object) {
        final LifecycleEventObserver observer = lifecycleEventObserver(object);
        return new GenericLifecycleObserver() {
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                observer.onStateChanged(source, event);
            }
        };
    }

    /**
     * 把不同订阅方式的订阅者，统一包装为一个LifecycleEventObserver
     * 事件改变时，统一调用LifecycleEventObserver类的onStateChanged()方法，再适配到不同的订阅方式
     *
     * @param object 订阅者
     */
    static LifecycleEventObserver lifecycleEventObserver(Object object) {
        //统一回调onStateChanged()方法的订阅方式
        boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
        //分发为详细的生命周期方法的订阅方式
        boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
        //实现了2种方式的接口，则通过一个适配器来同时支持
        if (isLifecycleEventObserver && isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
                    (LifecycleEventObserver) object);
        }
        //只需要详细方式的回调，也通过适配器，但把第二个参数置空即可
        if (isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
        }
        //统一回调方式，直接返回，不需要适配器处理
        if (isLifecycleEventObserver) {
            return (LifecycleEventObserver) object;
        }
        //获取类的Class
        final Class<?> klass = object.getClass();
        //获取构造类型，编译时生成或运行时反射
        int type = getObserverConstructorType(klass);
        //通过注解 + APT编译时生成的Class的方式订阅
        if (type == GENERATED_CALLBACK) {
            List<Constructor<? extends GeneratedAdapter>> constructors =
                    sClassToAdapters.get(klass);
            //单构造方法
            if (constructors.size() == 1) {
                GeneratedAdapter generatedAdapter = createGeneratedAdapter(
                        constructors.get(0), object);
                return new SingleGeneratedAdapterObserver(generatedAdapter);
            }
            //多构造方法
            GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
            for (int i = 0; i < constructors.size(); i++) {
                adapters[i] = createGeneratedAdapter(constructors.get(i), object);
            }
            return new CompositeGeneratedAdaptersObserver(adapters);
        }
        //通过注解 + 反射的方式订阅
        return new ReflectiveGenericLifecycleObserver(object);
    }

    /**
     * 反射创建适配类的实例
     *
     * @param constructor 适配类的构造方法
     * @param object      构造方法传了一个订阅者的实例参数
     * @return 适配类实例
     */
    private static GeneratedAdapter createGeneratedAdapter(
            Constructor<? extends GeneratedAdapter> constructor, Object object) {
        //noinspection TryWithIdenticalCatches
        try {
            return constructor.newInstance(object);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取APT方式生成的适配器类的构造方法
     */
    private static Constructor<? extends GeneratedAdapter> generatedConstructor(Class<?> klass) {
        try {
            Package aPackage = klass.getPackage();
            String name = klass.getCanonicalName();
            //获取全类名
            final String fullPackage = aPackage != null ? aPackage.getName() : "";
            //根据特定的规则，组合出适配器的类名
            final String adapterName = getAdapterName(fullPackage.isEmpty() ? name :
                    name.substring(fullPackage.length() + 1));
            //加载生成的适配器类
            @SuppressWarnings("unchecked") final Class<? extends GeneratedAdapter> aClass =
                    (Class<? extends GeneratedAdapter>) Class.forName(
                            fullPackage.isEmpty() ? adapterName : fullPackage + "." + adapterName);
            //如果找得到，则返回生成的适配器类的构造方法对象
            Constructor<? extends GeneratedAdapter> constructor =
                    aClass.getDeclaredConstructor(klass);
            //如果构造方法是私有的，把无视私有操作符，把访问限制设置为允许
            if (!constructor.isAccessible()) {
                constructor.setAccessible(true);
            }
            return constructor;
        } catch (ClassNotFoundException e) {
            //没有适配器类，只能使用反射
            return null;
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取订阅者的构造类型
     */
    private static int getObserverConstructorType(Class<?> klass) {
        //优先缓存中拿，找得到则直接返回
        Integer callbackCache = sCallbackCache.get(klass);
        if (callbackCache != null) {
            return callbackCache;
        }
        //找不到缓存，查询订阅的回调类型
        int type = resolveObserverCallbackType(klass);
        //查询到，加入缓存中
        sCallbackCache.put(klass, type);
        return type;
    }

    /**
     * 查询订阅者的回调类型
     */
    private static int resolveObserverCallbackType(Class<?> klass) {
        // anonymous class bug:35073837
        //获取不到类名，使用反射的方式
        if (klass.getCanonicalName() == null) {
            return REFLECTIVE_CALLBACK;
        }
        //获取APT方式生成的适配器类的构造方法
        Constructor<? extends GeneratedAdapter> constructor = generatedConstructor(klass);
        //获取成功，放进缓存
        if (constructor != null) {
            sClassToAdapters.put(klass, Collections
                    .<Constructor<? extends GeneratedAdapter>>singletonList(constructor));
            return GENERATED_CALLBACK;
        }
        //获取失败，则只能通过反射的方式回调，则通过反射查询加了注解的回调方法
        boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
        if (hasLifecycleMethods) {
            return REFLECTIVE_CALLBACK;
        }

        //没有查找到，去父类上找
        Class<?> superclass = klass.getSuperclass();
        List<Constructor<? extends GeneratedAdapter>> adapterConstructors = null;
        if (isLifecycleParent(superclass)) {
            if (getObserverConstructorType(superclass) == REFLECTIVE_CALLBACK) {
                return REFLECTIVE_CALLBACK;
            }
            adapterConstructors = new ArrayList<>(sClassToAdapters.get(superclass));
        }

        for (Class<?> intrface : klass.getInterfaces()) {
            if (!isLifecycleParent(intrface)) {
                continue;
            }
            if (getObserverConstructorType(intrface) == REFLECTIVE_CALLBACK) {
                return REFLECTIVE_CALLBACK;
            }
            if (adapterConstructors == null) {
                adapterConstructors = new ArrayList<>();
            }
            adapterConstructors.addAll(sClassToAdapters.get(intrface));
        }
        if (adapterConstructors != null) {
            sClassToAdapters.put(klass, adapterConstructors);
            return GENERATED_CALLBACK;
        }

        return REFLECTIVE_CALLBACK;
    }

    /**
     * 父类是否实现了LifecycleObserver接口
     */
    private static boolean isLifecycleParent(Class<?> klass) {
        return klass != null && LifecycleObserver.class.isAssignableFrom(klass);
    }

    /**
     * 根据订阅者的Class，拼接APT出生成的适配类
     * <p>
     * 例如：BroadcastRegistry.RegistryTableItem是订阅者类名
     * 则生成的适配类为BroadcastRegistry_RegistryTableItem_LifecycleAdapter
     */
    public static String getAdapterName(String className) {
        return className.replace(".", "_") + "_LifecycleAdapter";
    }

    private Lifecycling() {
    }
}